<template>
  <div class="todo-container">
    <div class="todo-wrap">
      <span>{{ todos }}</span>
      <TodoHeader :addTodo="addTodo"></TodoHeader>
      <!-- 通过props传递数据 -->
      <TodoMain :todos="todos" :updateDone="updateDone" :deleteTodo="deleteTodo"></TodoMain>
      <!-- 通过props传递数据 -->
      <TodoFooter :todos="todos" :todoIsDone="todoIsDone" :updateAllDone="updateAllDone" :deleteDoneTodo="deleteDoneTodo"></TodoFooter>
    </div>
  </div>
</template>

<script>
//引入子组件
import TodoHeader from "@/components/TodoHeader";
import TodoMain from "@/components/TodoMain";
import TodoFooter from "@/components/TodoFooter";
export default {
  name: "",
  components: {
    TodoHeader,
    TodoMain,
    TodoFooter,
  },
  data() {
    return {
      //整个案例的数据
      //响应式数据对象、数组[基本类型数据:变更、替换完成]
      //在读取的时候：需要把字符串转换为引用类型的数据
      //底下这行代码:本地存储有数据用本地存储的,本地存储没有数据【null】，至少是一个空数组！！！！
      todos:JSON.parse(localStorage.getItem('TODO'))||[]
    };
  },
  methods: {
    //父组件的方法:修改自身的数据done状态
    //第一个参数:子组件调用父亲的方法传递事件的ID
    //第二个参数:复选框的勾选状态【true|false】
    updateDone(id, done) {
      //第一种写法:for循环
      // for (var i = 0; i < this.todos.length; i++) {
      //   if (this.todos[i].id == id) {
      //     this.todos[i].done = done;
      //   }
      // }

      //第二种手段:forEach
      // this.todos.forEach((todo) => {
      //   if (todo.id == id) {
      //     todo.done = done;
      //   }
      // });


      //数组map替换：Vue框架也能检测到变化。达到数据变化，视图跟着变化
      // this.todos = this.todos.map(item=>{
      //       if(item.id==id){
      //         return {
      //             ...item,
      //             done
      //         }
      //       }
      //       return item;
      // });
      
      //数组的替换
      this.todos = this.todos.map(item=>item.id==id?{...item,done}:item)

    },
    //父组件App的方法,用于删除某一个事件
    deleteTodo(id){
       //Vue检测数组的变化:变更 shift|unshift|push|pop|splice|sort|reverse
       //替换:利用新的数组替换为起始的数组
       //下面这行代码:利用新的数组替换起始的数组  箭头函数简写方式：把函数体与关键字return同时省略
       this.todos = this.todos.filter(item=>item.id==id?false:true);

    },
    //父组件App的方法,用于向数组里面添加新的元素
    //形参todo,将来新增的事件【对象】
    addTodo(todo){
        //数组检测：变更，对于起始数组有影响，vue框架可以检测到数据变化，数据发生变化，视图跟这边。
        let repeat = this.todos.find(item=> item.title ==todo.title);
        //向父组件数组里面添加新的事件之前需要判断：判断这个事件有没有，如果有了，没必要新增，如果没有在新增。
        !repeat&&this.todos.push(todo);
    },
    //全部事件的勾选状态的修改
    updateAllDone(done){
         //数组的替换:map方法,简写的方式外层需要套一个小括号，把对象当中一个整体才能返回
         //不加小括号，认为对象花括号即为函数体，语法有错误！！！！
         this.todos = this.todos.map(item=>({...item,done}))
    },
    //删除掉已经完成的事件
    deleteDoneTodo(params){
      console.log(params);
      //需要把已经完成的事件进行过滤
      //数组的替换：filter过滤
      //已经做完的事情【done:true】不需要  需要的是未完成的事件【done:false】
      this.todos = this.todos.filter(item=>!item.done)
    }

  },
  //计算属性:利用已有的属性与属性值，计算出一个新的属性与属性值
  computed: {
      //计算属性有两种写法:函数写法、对象写法
      //计算属性一般步书写异步语句，watch里面可以书写异步
      todoIsDone(){
         //注意一件事情：filter方法返回一个数组
         //todoIsDone计算出来属性的属性值是一个数组【数组里面装载已经完成的事件】
         return this.todos.filter(item=>item.done)
      }
  },

  //watch监听:监听响应式属性的属性值的变化！！！！
  watch:{
     //监听属性todos,数组！！！对于监听的是数组：替换、变更。监听都可以检测到！！！
     todos(){
        //持久化存储数据:引用类型的数据需要通过JSON.stringify转换为字符串存储
         localStorage.setItem("TODO",JSON.stringify(this.todos));
     }
  }
};
</script>

<style scoped>
</style>
